package com.gengzp.rpc.utils;

import com.fasterxml.jackson.core.type.TypeReference;
import com.gengzp.rpc.core.RpcInvocationCoreFunc;
import com.gengzp.rpc.exception.RpcException;
import com.gengzp.rpc.model.common.resp.RpcResponse;
import com.gengzp.rpc.model.remoteTransaction.req.RpcRollbackRequest;
import com.gengzp.rpc.model.serviceRegistration.resp.SearchServiceRegistrationResp;
import com.gengzp.rpc.tools.RpcHttpRequester;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.gengzp.rpc.constants.RpcHttpRequestUrlConstants.HTTP_REQUEST_URL_PREFIX;
import static com.gengzp.rpc.constants.RpcUriConstants.RPC_PRODUCER_CONTROLLER_URI;
import static com.gengzp.rpc.constants.RpcUriConstants.RPC_PRODUCER_METHOD_URI;

/**
 * @ClassName RpcUtils
 * @Description rpc远程调用工具类
 * @Author gengzp
 * @Date 2025/8/25 14:26
 */
@Component
public class RpcUtils {

    private static RpcInvocationCoreFunc rpcInvocationCoreFunc;

    public RpcUtils(RpcInvocationCoreFunc rpcInvocationCoreFunc) {
        RpcUtils.rpcInvocationCoreFunc = rpcInvocationCoreFunc;
    }

    /**
     * 根据服务名查询服务注册信息
     *
     * @param serviceName 服务名
     * @return 服务注册信息
     */
    public static List<SearchServiceRegistrationResp> getAllServiceRegistrationInformationByServiceName(String serviceName) {
        return rpcInvocationCoreFunc.getAllServiceRegistrationInformationByServiceName(serviceName);
    }

    /**
     * 根据服务名获取对应服务的所有在线实例地址 (ip:端口号)
     *
     * @param serviceName 远程服务名
     * @return 远程服务地址, {ip}:{端口号}
     */
    public static List<String> getAllAddressesByServiceName(String serviceName) throws RpcException {
        return getAllRemoteUrlsByServiceName(serviceName).stream()
                .map(v -> v.replace(RPC_PRODUCER_CONTROLLER_URI + RPC_PRODUCER_METHOD_URI, "")
                        .replace(HTTP_REQUEST_URL_PREFIX, "")).collect(Collectors.toList());
    }

    /**
     * 根据服务名获取对应服务的所有在线实例地址 (ip:端口号)
     * <p> 该方法会通过随机的方式进行简单的负载均衡 </p>
     *
     * @param serviceName 远程服务名
     * @return 远程服务地址, {ip}:{端口号}
     */
    public static String getAddressByServiceName(String serviceName) throws RpcException {
        return rpcInvocationCoreFunc.getRemoteServiceAddress(serviceName)
                .replace(RPC_PRODUCER_CONTROLLER_URI + RPC_PRODUCER_METHOD_URI, "")
                .replace(HTTP_REQUEST_URL_PREFIX, "");
    }

    /**
     * 根据服务名获取对应服务的所有在线实例远程调用地址
     *
     * @param serviceName 远程服务名
     * @return 远程服务地址, 完整的 http://{ip}:{端口}/{远程调用uri}
     */
    public static List<String> getAllRemoteUrlsByServiceName(String serviceName) throws RpcException {
        return rpcInvocationCoreFunc.getRemoteServiceAddresses(serviceName);
    }

    /**
     * 根据服务名获取对应的在线实例远程调用地址
     * <p> 该方法会通过随机的方式进行简单的负载均衡 </p>
     *
     * @param serviceName 服务名
     * @return 在线实例地址, 完整的 http://{ip}:{端口}/{远程调用uri}
     */
    public static String getRemoteUrlByServiceName(String serviceName) throws RpcException {
        return rpcInvocationCoreFunc.getRemoteServiceAddress(serviceName);
    }

    /**
     * 执行回滚请求
     *
     * @param requestUrl    回滚请求地址
     * @param requestHeader 回滚请求头
     * @param rollbackReq   回滚请求参数
     * @return 回滚结果
     */
    public static RpcResponse<Object> doRollbackTransaction(String requestUrl,
                                                            Map<String, String> requestHeader,
                                                            RpcRollbackRequest rollbackReq) throws RpcException {
        return RpcHttpRequester.post(requestUrl, rollbackReq, requestHeader, new TypeReference<>() {
        });
    }

}
